package com.jec.module.sysconfig.controller;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jec.module.sysconfig.dao.NumberEntryRepository;
import com.jec.module.sysconfig.entity.BroadcastConfig;
import com.jec.module.sysconfig.entity.Clock;
import com.jec.module.sysconfig.entity.DigitTrunk;
import com.jec.module.sysconfig.entity.MeetingConfig;
import com.jec.module.sysconfig.entity.NetUnitConfig;
import com.jec.module.sysconfig.entity.NumberEntry;
import com.jec.module.sysconfig.entity.PhoneStation;
import com.jec.module.sysconfig.entity.RelayBusiness;
import com.jec.module.sysconfig.entity.TerminalBusiness;
import com.jec.module.sysconfig.entity.TerminalKeyConfig;
import com.jec.module.sysconfig.entity.TonglingConfig;
import com.jec.module.sysconfig.service.Configors;
import com.jec.module.sysconfig.service.DeviceDownloadService;
import com.jec.module.sysconfig.service.DownloadService;
import com.jec.module.sysconfig.service.TimeDownloadService;
import com.jec.module.sysconfig.service.configor.ClockConfigor;
import com.jec.utils.Inputs;
import com.jec.utils.Response;

/**
 * Created by jeremyliu on 7/4/16.
 */
@Controller
@RequestMapping(value = "/config")
public class ConfigController implements ApplicationContextAware{

    //@Resource
    //private ConfigService configService;

    @Resource
    private TimeDownloadService timeDownloadService;

    @Autowired
    private NumberEntryRepository numberEntryRepository;

    private Map<String, DownloadService> downloadServices = new HashMap<>();

    private Map<String, Class<? extends NetUnitConfig>> strMap = new HashMap<>();

    private ApplicationContext context;
        
    @Autowired
    private Configors configors;

    @PostConstruct
    public void init(){
        downloadServices.put("card", (DownloadService)context.getBean("cardDownloadService"));
        downloadServices.put("clock", (DownloadService)context.getBean("clockDownloadService"));
        downloadServices.put("meeting", (DownloadService)context.getBean("meetingDownloadService"));
        downloadServices.put("tongling", (DownloadService)context.getBean("tonglingDownloadService"));
        downloadServices.put("digittrunk", (DownloadService)context.getBean("digitTrunkDownloadService"));
        downloadServices.put("userdata", (DownloadService)context.getBean("numberEntryDownloadService"));
        downloadServices.put("broadcast", (DownloadService)context.getBean("broadcastDownloadService"));
        downloadServices.put("phonestation", (DownloadService)context.getBean("phoneStationDownloadService"));
        downloadServices.put("vdr", (DownloadService)context.getBean("vdrDownloadService"));
        downloadServices.put("terminalbusiness", (DownloadService)context.getBean("terminalBusinessDownloadService"));
        downloadServices.put("terminalkey", (DownloadService)context.getBean("terminalKeyDownloadService"));
        downloadServices.put("relay", (DownloadService)context.getBean("relayBusinessDownloadService"));
        strMap.put("clock", Clock.class);
        strMap.put("meeting", MeetingConfig.class);
        strMap.put("tongling", TonglingConfig.class);
        strMap.put("digittrunk", DigitTrunk.class);
        strMap.put("userdata", NumberEntry.class);
        strMap.put("broadcast", BroadcastConfig.class);
        strMap.put("phonestation", PhoneStation.class);
    }

    @RequestMapping(value = "download/{type}", method = RequestMethod.POST)
    public
    @ResponseBody
    Response download(@PathVariable(value = "type") String type,
                     @RequestParam(value = "netunit", required = false, defaultValue = "0") int netunitId){
        DownloadService downloadService = downloadServices.get(type);
        if(downloadService == null)
            return Response.Builder().status(Response.STATUS_PARAM_ERROR);
        if(netunitId > 0)
            return downloadService.download(netunitId);
        else
            return downloadService.download();
    }

    @RequestMapping(value = "download/device/{type}", method = RequestMethod.POST)
    public
    @ResponseBody
    Response downloadDevice(@PathVariable(value = "type") String type,
                            @RequestParam(value = "device", required = false, defaultValue = "") String deviceNumber,
                      @RequestParam(value = "netunit", required = false, defaultValue = "0") int netunitId){
        DeviceDownloadService downloadService = (DeviceDownloadService)downloadServices.get(type);
        if(downloadService == null)
            return Response.Builder().status(Response.STATUS_PARAM_ERROR);
        if(!deviceNumber.equals("")){
            return downloadService.download(deviceNumber);
        }else if(netunitId>0)
            return downloadService.download(netunitId);
        else
            return downloadService.download();
    }

    @RequestMapping(value = "download/time", method = RequestMethod.POST)
    public
    @ResponseBody
    Response download(@RequestParam(value = "netunit", required = false, defaultValue = "0") int netunitId,
                      @RequestParam(value = "time", required = false, defaultValue = "-1") long ts){
        if(netunitId > 0)
            return timeDownloadService.download(netunitId, ts);
        else
            return timeDownloadService.download(ts);
    }

    @RequestMapping(value = "save/digittrunk", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public
    @ResponseBody
    Response digittrunk(@RequestBody DigitTrunk digittrunk){
    	
    	return configors.getDigitTrunkConfigor().saveOrUpdate(digittrunk, digittrunk.getId() == 0);
    }

    @RequestMapping(value = "save/meeting", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public
    @ResponseBody
    Response meeting(@RequestBody MeetingConfig meetingConfig){
    	try {
	    	Inputs.at(meetingConfig.getName(), "业务名称")._notEmpty()._max(20);
	    	Inputs.at(meetingConfig.getCode(), "业务号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
    	return configors.getMeetingConfigor().saveOrUpdate(meetingConfig, meetingConfig.getId() == 0);
    }

    @RequestMapping(value = "save/clock", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response clock(@RequestBody Clock clockConfig){
    	ClockConfigor configor = configors.getClockConfigor();
    	boolean exist = configor.hasConfigOnNetunit(clockConfig.getNetunit());
    	return configors.getClockConfigor().saveOrUpdate(clockConfig, !exist);
    }

    @RequestMapping(value = "save/tongling", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response tongling(@RequestBody TonglingConfig tonglingConfig){
    	try {
	    	Inputs.at(tonglingConfig.getName(), "业务名称")._notEmpty()._max(20);
	    	Inputs.at(tonglingConfig.getCode(), "业务号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
        return configors.getTonglingConfigor().saveOrUpdate(tonglingConfig, tonglingConfig.getId() == 0);
    }

    @RequestMapping(value = "save/userdata", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response userdata(@RequestBody NumberEntry numberEntry){
    	try {
	    	Inputs.at(numberEntry.getNumber(), "用户号码")._notEmpty()._max(5)._bcd();
	    	if(numberEntry.isHotlineEnable())
	    		Inputs.at(numberEntry.getHotlineNumber(), "热线号码")._notEmpty()._max(5)._bcd();
	    	if(numberEntry.isBusingcfEnable())
	    		Inputs.at(numberEntry.getBusingcfNumber(), "遇忙转移号码")._notEmpty()._max(5)._bcd();
	    	if(numberEntry.isFollowcfEnable())
	    		Inputs.at(numberEntry.getFollowcfNumber(), "跟随转移号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
        return configors.getNumberEntryConfigor().saveOrUpdate(numberEntry, numberEntry.getId() == 0);
    }

    @RequestMapping(value = "save/broadcast", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response broadcast(@RequestBody BroadcastConfig broadcastConfig){
    	try {
	    	Inputs.at(broadcastConfig.getName(), "业务名称")._notEmpty()._max(20);
	    	Inputs.at(broadcastConfig.getCode(), "业务号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
        return configors.getBroadcastConfigor().saveOrUpdate(broadcastConfig, broadcastConfig.getId() == 0);
    }

    @RequestMapping(value = "save/phonestation", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response phonestation(@RequestBody PhoneStation phoneStation){
    	try {
	    	Inputs.at(phoneStation.getName(), "业务名称")._notEmpty()._max(20);
	    	Inputs.at(phoneStation.getCode(), "业务号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
        return configors.getPhoneStationConfigor().saveOrUpdate(phoneStation, phoneStation.getId() == 0);
    }

    @RequestMapping(value = "save/terminalbusiness", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response terminalBusiness(@RequestBody TerminalBusiness terminalBusiness){
        return configors.getTerminalBusinessConfigor().saveOrUpdate(terminalBusiness, terminalBusiness.getId() == 0);
    }

    @RequestMapping(value = "save/terminalkey", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response terminalKey(@RequestBody TerminalKeyConfig terminalKeyConfig){
        return configors.getTerminalKeyConfigor().saveOrUpdate(terminalKeyConfig, terminalKeyConfig.getId() == 0);
    }
    
    @RequestMapping(value = "save/relay", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public @ResponseBody
    Response relayBusiness(@RequestBody RelayBusiness relayBusiness){
    	try {
	    	Inputs.at(relayBusiness.getName(), "业务名称")._notEmpty()._max(20);
	    	Inputs.at(relayBusiness.getCode(), "业务号码")._notEmpty()._max(5)._bcd();
    	} catch(Exception e) {
    		return Response.Builder().status(Response.STATUS_PARAM_ERROR).message(e.getMessage());
    	}
        return configors.getRelayBusinessConfigor().saveOrUpdate(relayBusiness, relayBusiness.getId() == 0);
    }

    @RequestMapping(value = "remove/{type}", method = RequestMethod.DELETE)
    @ResponseBody
    Response removeConfig(@PathVariable(value = "type") String type,
            @RequestParam(value="netunit", required = false, defaultValue = "-1") int netunit,
                          @RequestParam(value="id", required = false, defaultValue = "-1") int id){
        
        return configors.remove(type, netunit, id);
    }

    @RequestMapping(value = "{type}", method = RequestMethod.GET)
    public @ResponseBody
    Response index(@RequestParam(value="page", required = false, defaultValue = "1") int page,
                   @RequestParam(value="pagesize", required = false, defaultValue = "20") int pageSize,
                   @PathVariable(value="type") String type){
        if(page <= 0)
            page = 1;
        if(pageSize <= 0)
            pageSize = 10;
        
        return configors.index(type, page, pageSize);

    }

    @RequestMapping(value = "numberentry", method = RequestMethod.GET)
    public @ResponseBody
    Response getNumberEnties(){
        return Response.Builder(numberEntryRepository.findAll());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}
